package com.zeyi.chat.controller;

import com.alibaba.fastjson.JSON;
import com.zeyi.chat.dto.Chat;
import com.zeyi.chat.dto.Message;
import com.zeyi.chat.manager.StageManager;
import com.zeyi.chat.manager.UserManager;
import com.zeyi.chat.po.ChatGroup;
import com.zeyi.chat.po.User;
import com.zeyi.chat.utils.AvatarUtil;
import com.zeyi.chat.utils.FXMLUtil;
import com.zeyi.chat.utils.SocketUtil;
import com.zeyi.chat.views.ChatContentListItem;
import com.zeyi.chat.views.CircleBorder;
import com.zeyi.chat.views.MemberListItem;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Callback;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zeyi
 */
public class HomeController {
    private static HomeController instance;
    @FXML
    private Pane chatAreaTop;

    @FXML
    private Pane wrapContainer;

    @FXML
    private ImageView myAvatar;

    @FXML
    private Pane chatContainer;

    @FXML
    private ListView<Chat> chatList;

    @FXML
    private Label chattingName;

    @FXML
    private ImageView minIcon;

    private Stage myInfoStage; //我的信息窗口

    private Stage chatInfoStage; //聊天信息窗口

    public static HomeController getInstance() {
        return instance;
    }

    /**
     * 设置圆角头像
     */
    private void setCircleAvatar(ImageView avatar, double radius) {
        Rectangle rectangle = new Rectangle(avatar.prefWidth(-1), avatar.prefHeight(-1));
        rectangle.setArcHeight(radius);
        rectangle.setArcWidth(radius);
        avatar.setClip(rectangle);
    }

    private void setCircleAvatar(ImageView avatar) {
        Rectangle rectangle = new Rectangle(avatar.prefWidth(-1), avatar.prefHeight(-1));
        rectangle.setArcHeight(avatar.prefHeight(-1));
        rectangle.setArcWidth(avatar.prefWidth(-1));
        avatar.setClip(rectangle);
    }

    @FXML
    private void initialize() {
        instance = this;
        User user = UserManager.getCurrentUser();
        myAvatar.setImage(new Image(AvatarUtil.suffix + user.getAvatar()));
        setCircleAvatar(myAvatar, 15);
        chatList.setCellFactory(new Callback<ListView<Chat>, ListCell<Chat>>() {
            @Override
            public ListCell<Chat> call(ListView<Chat> param) {
                ListCell<Chat> cell = new ListCell<Chat>() {
                    @Override
                    protected void updateItem(Chat chat, boolean empty) {
                        super.updateItem(chat, empty);
                        if (!empty) {
                            Parent root = FXMLUtil.createRoot("/Fxml/ChatListItem.fxml");
                            ImageView chatAvatar = (ImageView) root.lookup("#chatAvatar");
                            if (chat.getCreateId() == null) {
                                root.setId("private" + chat.getId());
                                if (chat.getIsOnline()) {
                                    chatAvatar.setImage(new Image(AvatarUtil.suffix + chat.getAvatar()));
                                } else {
                                    chatAvatar.setImage(new Image("/images/avatar/offline.png"));
                                }
                                setCircleAvatar(chatAvatar);
                            } else {
                                root.setId("group" + chat.getId());
                                chatAvatar.setImage(new Image(AvatarUtil.suffix + chat.getAvatar()));
                                setCircleAvatar(chatAvatar, 10);
                            }
                            Label chatName = (Label) root.lookup("#chatName");
                            chatName.setText(chat.getChatName());
                            this.setGraphic(root);
                        } else {
                            this.setGraphic(null);
                        }
                    }
                };
                return cell;
            }
        });
        ObservableList<Chat> chats = FXCollections.observableArrayList(user.getChatList());
        chatList.setItems(chats);
    }

    @FXML
    public void minimize(MouseEvent mouseEvent) {
        Stage stage = (Stage) minIcon.getScene().getWindow();
        stage.setIconified(true);
    }

    @FXML
    public void onClose(MouseEvent mouseEvent) {
        System.exit(0);
    }

    /**
     * 选择聊天对象
     */
    @FXML
    public void selectChat(MouseEvent mouseEvent) {
        Chat receiver = chatList.getSelectionModel().getSelectedItem();
        if (mouseEvent.getButton() == MouseButton.PRIMARY) {
            if (receiver == null) return;
            chattingName.setText(receiver.getChatName());
            UserManager.setChat(receiver);
            chatAreaTop.setVisible(true);
            String chatName = receiver.getCreateId() == null ? "private" : "group";
            chatName += receiver.getId();
            //清除未读消息数
            Label messageNum = (Label) chatList.lookup("#" + chatName).lookup("#messageNum");
            messageNum.setText("0");
            messageNum.setVisible(false);

            //显示聊天对象对应的聊天页
            Pane chat = StageManager.getChat(chatName);
            if (chat == null) {
                wrapContainer.getChildren().clear();
                if (receiver.getCreateId() == null) {
                    chat = (Pane) FXMLUtil.createRoot("/Fxml/PrivateChat.fxml");
                    StageManager.addChat("private" + receiver.getId(), chat);
                } else {
                    chat = (Pane) FXMLUtil.createRoot("/Fxml/GroupChat.fxml");
                    StageManager.addChat("group" + receiver.getId(), chat);
                }
            } else {
                if (chat == chatContainer) return;
                wrapContainer.getChildren().clear();
            }
            if (receiver.getCreateId() != null) {
                //获取群成员
                Message message = new Message("ChatHandler/getGroupMember", "ChatHandler/getGroupMember", String.valueOf(receiver.getId()));
                SocketUtil.send(message);
            }
            wrapContainer.getChildren().add(chat);
            chatContainer = chat;
        } else {
            ContextMenu contextMenu = new ContextMenu();
            contextMenu.setStyle("-fx-padding: 5px 0;");
            int type;
            MenuItem menuItem;
            if (receiver.getCreateId() == null) {
                type = 0;
                menuItem = new MenuItem("删除好友");
            } else if (receiver.getCreateId().equals(UserManager.getCurrentUser().getId())) {
                type = 1;
                menuItem = new MenuItem("删除群");
            } else {
                type = 2;
                menuItem = new MenuItem("退出群");
            }
            menuItem.setOnAction(event -> {
                Map<String, Integer> map = new HashMap<>();
                map.put("type", type);
                map.put("userId", UserManager.getCurrentUser().getId());
                map.put("deleteId", receiver.getId());
                SocketUtil.send(new Message("ChatHandler/deleteChat", "ChatHandler/deleteChat", JSON.toJSONString(map)));
            });
            contextMenu.getItems().add(menuItem);
            contextMenu.show(StageManager.getPrimaryStage(), mouseEvent.getScreenX(), mouseEvent.getScreenY());
        }
    }

    /**
     * 创建组
     */
    @FXML
    public void createGroup(MouseEvent mouseEvent) {
        if (StageManager.getGroupStage() != null) return;
        Stage stage = FXMLUtil.createStage("/Fxml/CreateGroup.fxml");
        StageManager.setGroupStage(stage);
    }

    /**
     * 加好友
     */
    @FXML
    public void addFriend(MouseEvent mouseEvent) {
        if (StageManager.getFriendStage() != null) return;
        Stage stage = FXMLUtil.createStage("/Fxml/AddFriend.fxml");
        StageManager.setFriendStage(stage);
    }

    /**
     * 聊天名鼠标悬浮
     */
    @FXML
    public void chatNameHover(MouseEvent mouseEvent) {
        chattingName.setUnderline(true);
    }

    /**
     * 聊天名鼠标离开
     */
    @FXML
    public void chatNameExit(MouseEvent mouseEvent) {
        chattingName.setUnderline(false);
    }

    /**
     * 查看聊天对象信息
     */
    @FXML
    public void getChatInfo(MouseEvent mouseEvent) {
        if (chatInfoStage != null) chatInfoStage.close();
        Chat chat = chatList.getSelectionModel().getSelectedItem();
        if (chat.getCreateId() == null) {
            SocketUtil.send(new Message("ChatHandler/userInfo", "ChatHandler/userInfo",
                    String.valueOf(chat.getId())));
        } else {
            SocketUtil.send(new Message("ChatHandler/groupInfo", "ChatHandler/groupInfo",
                    String.valueOf(chat.getId())));
        }
        chatInfoStage = FXMLUtil.createStage("/Fxml/ChatInfo.fxml");
        chatInfoStage.getScene().getRoot().setId(String.valueOf(chat.getId()));
    }

    /**
     * 查看自己信息
     */
    @FXML
    public void viewMyInfo(MouseEvent mouseEvent) {
        if (myInfoStage != null) myInfoStage.close();
        User currentUser = UserManager.getCurrentUser();
        myInfoStage = FXMLUtil.createStage("/Fxml/ChatInfo.fxml");
        myInfoStage.getScene().getRoot().setId(String.valueOf(UserManager.getCurrentUser().getId()));
        ChatInfoController.getInstance().displayUserInfo(currentUser, true);
    }

    /**
     *  显示聊天信息
     */
    public void displayChat(String chatId, User sender, String text, String type) {
        Pane chatContainer = StageManager.getChat(chatId);
        Stage stage = StageManager.getPrimaryStage();
        //聊天对象
        Node chat = chatList.lookup("#" + chatId);
        //正打开的聊天页
        Pane chatHistory = (Pane) stage.getScene().getRoot().lookup("#chatContainer");
        if (chatContainer == null) {
            chatContainer = type.equals("0") ? (Pane) FXMLUtil.createRoot("/Fxml/PrivateChat.fxml")
                    : (Pane) FXMLUtil.createRoot("/Fxml/GroupChat.fxml");
            ListView<Node> chatContent = (ListView<Node>) chatContainer.lookup("#chatContentList");
            chatContent.getItems().add(new ChatContentListItem().Other(sender, text, type));
            StageManager.addChat(chatId, chatContainer);

            Label messageNum = (Label) chat.lookup("#messageNum");
            messageNum.setText(Integer.parseInt(messageNum.getText()) + 1 + "");
            messageNum.setVisible(true);
        } else if (chatContainer != chatHistory) {
            ListView<Node> chatContent = (ListView<Node>) chatContainer.lookup("#chatContentList");
            chatContent.getItems().add(new ChatContentListItem().Other(sender, text, type));
            Label messageNum = (Label) chat.lookup("#messageNum");
            messageNum.setText(Integer.parseInt(messageNum.getText()) + 1 + "");
            messageNum.setVisible(true);
        } else {
            ListView<Node> chatContent = (ListView<Node>) chatContainer.lookup("#chatContentList");
            chatContent.getItems().add(new ChatContentListItem().Other(sender, text, type));
        }
        //显示预览消息
        Label chatBrief = (Label) chat.lookup("#chatBrief");
        Label chatTime = (Label) chat.lookup("#chatTime");
        Calendar calendar = Calendar.getInstance();
        chatTime.setText(calendar.get(Calendar.HOUR) + ":" + calendar.get(Calendar.MINUTE));
        String formatText = text.replaceAll("\n", "");
        if (type.equals("1")) {
            formatText = sender.getUsername() + ":" + formatText;
        }
        chatBrief.setText(formatText);
    }

    /**
     * 显示群成员
     */
    public void displayGroupMember(ChatGroup group) {
        Pane chat = StageManager.getChat("group" + group.getId());
        ListView<Node> memberList = (ListView<Node>) chat.lookup("#memberList");
        Label memberNum = (Label) chat.lookup("#memberNum");
        memberNum.setText("群成员(" + group.getMembers().size() + ")");
        memberList.getItems().clear();
        group.getMembers().forEach(user -> {
            Pane pane = new MemberListItem(user).create();
            memberList.getItems().add(pane);
        });
    }

    /**
     * 更新组信息
     */
    public void updateGroup(ChatGroup group) {
        if (group.getGroupName() != null) {
            Label chatName = (Label) chatList.lookup("#group" + group.getId()).lookup("#chatName");
            chatName.setText(group.getGroupName());
            Pane chat = StageManager.getChat("group" + group.getId());
            if (chat == chatContainer) {
                chattingName.setText(group.getGroupName());
            }
        }
        if (group.getAvatar() != null) {
            ImageView groupAvatar = (ImageView) chatList.lookup("#group" + group.getId()).lookup("#chatAvatar");
            groupAvatar.setImage(new Image(group.getAvatar(), groupAvatar.prefWidth(-1),
                    groupAvatar.prefHeight(-1), false, true));
        }
    }

    /**
     * 更新我的头像
     */
    public void updateMyAvatar(String avatar) {
        myAvatar.setImage(new Image(avatar, myAvatar.prefWidth(-1),
                myAvatar.prefHeight(-1), false, true));
    }
}
